package library.dao.mysql;

import library.exception.DataException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import library.server.Config;

public class ConnectionPool {

    public static final String DRIVER_CLASS = "com.mysql.jdbc.Driver";
    public static final String DB_URL = Config.getInstance().getValue("mysql.url");
    public static final String DB_USER = Config.getInstance().getValue("mysql.user");
    public static final String DB_PASSWORD = Config.getInstance().getValue("mysql.pass");
    protected static ConnectionPool instance = new ConnectionPool();
    private static BlockingQueue<Connection> connectionQueue = new LinkedBlockingQueue<Connection>();

    protected ConnectionPool() {
    }

    synchronized public Connection getConnection() throws DataException {
        Connection connection = null;
        while (connection == null) {
            try {
                if (connectionQueue.isEmpty()) {
                    Class.forName(DRIVER_CLASS);
                    connection = DriverManager.getConnection(DB_URL, DB_USER,
                            DB_PASSWORD);
                    connection.setAutoCommit(false);
                } else {
                    connection = connectionQueue.take();
                    if (!connection.isValid(0)) {
                        connection = null;
                    }
                }
            } catch (ClassNotFoundException e) {
                throw new DataException(e);
            } catch (InterruptedException e) {
                throw new DataException(e);
            } catch (SQLException e) {                
                throw new DataException(e);
            }
        }
        return connection;
    }

    public void freeConnection(Connection connection) {
        try {
            connectionQueue.put(connection);
        } catch (InterruptedException e) {
            System.err.println(e.toString());
        }
    }

    public static ConnectionPool getInstance() {
        return instance;
    }
}
